using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using ERP.ERPModels.Production.MasterData;
using ERP.ERPModels.Production.ProductionManagement;
using ERP.ERPModels.RepositoryManage;
using ERP.ProductionManage.Dtos;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace ERP.ProductionManage
{
    /// <summary>
    /// 生产退料服务实现
    /// </summary>
    public class ProductionReturnService : ApplicationService, IProductionReturnService
    {
        private readonly IRepository<ProductionReturn, int> _productionReturnRepository;
        private readonly IRepository<ProductionReturnDetail, int> _returnDetailRepository;
        private readonly IRepository<Material, int> _materialRepository;
        private readonly IRepository<Inventory, int> _inventoryRepository;
        private readonly IRepository<Warehouse, int> _warehouseRepository;
        private readonly IRepository<ProductionWorkOrders, int> _productionWorkOrdersRepository;
        private readonly ILogger<ProductionReturnService> _logger;

        public ProductionReturnService(
            IRepository<ProductionReturn, int> productionReturnRepository,
            IRepository<ProductionReturnDetail, int> returnDetailRepository,
            IRepository<Material, int> materialRepository,
            IRepository<Inventory, int> inventoryRepository,
            IRepository<Warehouse, int> warehouseRepository,
            IRepository<ProductionWorkOrders, int> productionWorkOrdersRepository,
            ILogger<ProductionReturnService> logger)
        {
            _productionReturnRepository = productionReturnRepository;
            _returnDetailRepository = returnDetailRepository;
            _materialRepository = materialRepository;
            _inventoryRepository = inventoryRepository;
            _warehouseRepository = warehouseRepository;
            _productionWorkOrdersRepository = productionWorkOrdersRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取生产退料分页列表
        /// </summary>
        public async Task<PagedResultDto<ProductionReturnDto>> GetListAsync(GetProductionReturnInputDto input)
        {
            var query = await _productionReturnRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(x => x.ReturnCode.Contains(input.Keyword) ||
                                        x.ReturnName.Contains(input.Keyword) ||
                                        x.WorkOrder.Contains(input.Keyword));
            }

            if (!string.IsNullOrWhiteSpace(input.ReturnCode))
            {
                query = query.Where(x => x.ReturnCode.Contains(input.ReturnCode));
            }

            if (!string.IsNullOrWhiteSpace(input.ReturnName))
            {
                query = query.Where(x => x.ReturnName.Contains(input.ReturnName));
            }

            if (!string.IsNullOrWhiteSpace(input.WorkOrder))
            {
                query = query.Where(x => x.WorkOrder.Contains(input.WorkOrder));
            }

            if (input.WarehouseId.HasValue)
            {
                query = query.Where(x => x.WarehouseId == input.WarehouseId.Value);
            }

            if (!string.IsNullOrWhiteSpace(input.Status))
            {
                query = query.Where(x => x.Status == input.Status);
            }

            if (input.ReturnDateStart.HasValue)
            {
                query = query.Where(x => x.ReturnDate >= input.ReturnDateStart.Value.Date);
            }

            if (input.ReturnDateEnd.HasValue)
            {
                query = query.Where(x => x.ReturnDate <= input.ReturnDateEnd.Value.Date.AddDays(1));
            }

            // 应用排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(x => x.Id);
            }

            var totalCount = await query.CountAsync();
            var items = await query.Skip(input.SkipCount).Take(input.MaxResultCount).ToListAsync();

            var dtos = new List<ProductionReturnDto>();
            foreach (var item in items)
            {
                dtos.Add(await MapToDto(item));
            }

            return new PagedResultDto<ProductionReturnDto>(totalCount, dtos);
        }

        /// <summary>
        /// 获取生产退料详情
        /// </summary>
        public async Task<ProductionReturnDto> GetAsync(int id)
        {
            var entity = await _productionReturnRepository.GetAsync(id);
            var dto = await MapToDto(entity);
            dto.Details = await GetReturnDetailsAsync(id);
            return dto;
        }

        /// <summary>
        /// 创建生产退料
        /// </summary>
        public async Task<ProductionReturnDto> CreateAsync(CreateProductionReturnDto input)
        {
            var warehouse = await _warehouseRepository.GetAsync(input.WarehouseId);
            
            var entity = new ProductionReturn
            {
                ReturnCode = await GenerateReturnCodeAsync(),
                ReturnName = input.ReturnName,
                WorkOrder = input.WorkOrder,
                WarehouseId = input.WarehouseId,
                WarehouseName = warehouse.WarehouseName,
                ReturnDate = input.ReturnDate,
                Remark = input.Remark,
                Status = "草稿"
            };

            entity = await _productionReturnRepository.InsertAsync(entity, true);
            _logger.LogInformation("创建生产退料成功，ID: {Id}, 退料单编号: {ReturnCode}", entity.Id, entity.ReturnCode);

            return await MapToDto(entity);
        }

        /// <summary>
        /// 更新生产退料
        /// </summary>
        public async Task<ProductionReturnDto> UpdateAsync(int id, UpdateProductionReturnDto input)
        {
            var entity = await _productionReturnRepository.GetAsync(id);
            var warehouse = await _warehouseRepository.GetAsync(input.WarehouseId);

            entity.ReturnName = input.ReturnName;
            entity.WorkOrder = input.WorkOrder;
            entity.WarehouseId = input.WarehouseId;
            entity.WarehouseName = warehouse.WarehouseName;
            entity.ReturnDate = input.ReturnDate;
            entity.Remark = input.Remark;
            
            // 如果传入了状态，则更新状态
            if (!string.IsNullOrWhiteSpace(input.Status))
            {
                entity.Status = input.Status;
            }

            entity = await _productionReturnRepository.UpdateAsync(entity, true);
            _logger.LogInformation("更新生产退料成功，ID: {Id}, 状态: {Status}", entity.Id, entity.Status);

            return await MapToDto(entity);
        }

        /// <summary>
        /// 删除生产退料
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            // 删除退料明细
            var details = await _returnDetailRepository.GetListAsync(x => x.ProductionReturnId == id);
            foreach (var detail in details)
            {
                await _returnDetailRepository.DeleteAsync(detail);
            }

            // 删除退料主记录
            await _productionReturnRepository.DeleteAsync(id);
            _logger.LogInformation("删除生产退料成功，ID: {Id}", id);
        }

        /// <summary>
        /// 生成退料单编号
        /// </summary>
        public async Task<string> GenerateReturnCodeAsync()
        {
            var today = DateTime.Now.ToString("yyyyMMdd");
            var prefix = $"RT{today}";

            var query = await _productionReturnRepository.GetQueryableAsync();
            var maxCode = await query
                .Where(x => x.ReturnCode.StartsWith(prefix))
                .Select(x => x.ReturnCode)
                .OrderByDescending(x => x)
                .FirstOrDefaultAsync();

            var sequence = 1;
            if (!string.IsNullOrEmpty(maxCode) && maxCode.Length > prefix.Length)
            {
                var sequenceStr = maxCode.Substring(prefix.Length);
                if (int.TryParse(sequenceStr, out var lastSequence))
                {
                    sequence = lastSequence + 1;
                }
            }

            return $"{prefix}{sequence:D4}";
        }

        /// <summary>
        /// 获取退料明细列表
        /// </summary>
        public async Task<List<ProductionReturnDetailDto>> GetReturnDetailsAsync(int returnId)
        {
            var details = await _returnDetailRepository.GetListAsync(x => x.ProductionReturnId == returnId);
            var result = new List<ProductionReturnDetailDto>();

            foreach (var detail in details)
            {
                result.Add(await MapToDetailDto(detail));
            }

            return result;
        }

        /// <summary>
        /// 添加退料明细
        /// </summary>
        public async Task<ProductionReturnDetailDto> CreateReturnDetailAsync(CreateProductionReturnDetailDto input)
        {
            var entity = new ProductionReturnDetail
            {
                ProductionReturnId = input.ProductionReturnId,
                MaterialCode = input.MaterialCode,
                MaterialName = input.MaterialName,
                Size = input.Size,
                Unit = input.Unit,
                Num = input.Num,
                Batch = input.Batch,
                WarehouseId = input.WarehouseId,
                WarehouseName = input.WarehouseName
            };

            entity = await _returnDetailRepository.InsertAsync(entity, true);
            _logger.LogInformation("添加退料明细成功，ID: {Id}, 退料ID: {ReturnId}, 物料编码: {MaterialCode}", 
                entity.Id, entity.ProductionReturnId, entity.MaterialCode);

            return await MapToDetailDto(entity);
        }

        /// <summary>
        /// 删除退料明细
        /// </summary>
        public async Task DeleteReturnDetailAsync(int detailId)
        {
            await _returnDetailRepository.DeleteAsync(detailId);
            _logger.LogInformation("删除退料明细成功，ID: {Id}", detailId);
        }

        /// <summary>
        /// 执行退料操作（更新库存）
        /// </summary>
        public async Task ExecuteReturnAsync(int returnId)
        {
            var returnEntity = await _productionReturnRepository.GetAsync(returnId);
            var details = await _returnDetailRepository.GetListAsync(x => x.ProductionReturnId == returnId);

            if (!details.Any())
            {
                throw new InvalidOperationException("退料单没有明细，无法执行退料");
            }

            foreach (var detail in details)
            {
                // 查找或创建库存记录
                var inventoryQuery = await _inventoryRepository.GetQueryableAsync();
                var inventory = await inventoryQuery
                    .Where(x => x.ProductItem == detail.MaterialCode && 
                               x.Warehouse == detail.WarehouseName)
                    .FirstOrDefaultAsync();

                if (inventory != null)
                {
                    // 更新现有库存
                    inventory.GalleryNumber += detail.Num;
                    await _inventoryRepository.UpdateAsync(inventory);
                }
                else
                {
                    // 创建新的库存记录
                    var newInventory = new Inventory
                    {
                        ProductItem = detail.MaterialCode,
                        ProductName = detail.MaterialName,
                        Specs = detail.Size,
                        GalleryNumber = detail.Num,
                        Unit = detail.Unit,
                        Storage = detail.Batch,
                        Warehouse = detail.WarehouseName,
                        StorageDate = DateTime.Now,
                        Storagevalidity = DateTime.Now.AddYears(1) // 默认有效期1年
                    };
                    await _inventoryRepository.InsertAsync(newInventory);
                }

                _logger.LogInformation("退料更新库存成功，物料编码: {MaterialCode}, 退料数量: {Num}, 仓库: {Warehouse}", 
                    detail.MaterialCode, detail.Num, detail.WarehouseName);
            }

            // 更新退料单状态
            returnEntity.Status = "已退料";
            await _productionReturnRepository.UpdateAsync(returnEntity);

            _logger.LogInformation("执行退料操作成功，退料单ID: {ReturnId}", returnId);
        }

        /// <summary>
        /// 获取仓库选择列表
        /// </summary>
        public async Task<List<WarehouseSelectDto>> GetWarehousesForSelectAsync()
        {
            var warehouses = await _warehouseRepository.GetListAsync();
            return warehouses.Select(x => new WarehouseSelectDto
            {
                Id = x.Id,
                WarehouseName = x.WarehouseName,
                WarehouseAddress = x.WarehouseAddress
            }).ToList();
        }

        /// <summary>
        /// 获取物料选择列表（用于退料）
        /// </summary>
        public async Task<PagedResultDto<MaterialSelectDto>> GetMaterialsForReturnAsync(GetProductSelectInputDto input)
        {
            var query = await _materialRepository.GetQueryableAsync();
            
            // 只选择物料（MaterielTypePid = 0）
            query = query.Where(m => m.MaterielTypePid == 0);
            
            // 关键字搜索
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(m => 
                    m.MaterielCode.Contains(input.Keyword) ||
                    m.MaterielName.Contains(input.Keyword) ||
                    m.Specifications.Contains(input.Keyword));
            }
            
            // 物料编码搜索
            if (!string.IsNullOrWhiteSpace(input.MaterielCode))
            {
                query = query.Where(m => m.MaterielCode.Contains(input.MaterielCode));
            }
            
            // 物料名称搜索
            if (!string.IsNullOrWhiteSpace(input.MaterielName))
            {
                query = query.Where(m => m.MaterielName.Contains(input.MaterielName));
            }
            
            var totalCount = await AsyncExecuter.CountAsync(query);
            
            query = query.OrderBy(m => m.MaterielCode)
                        .Skip(input.SkipCount)
                        .Take(input.MaxResultCount);
            
            var materials = await AsyncExecuter.ToListAsync(query);
            
            var materialDtos = materials.Select(m => new MaterialSelectDto
            {
                Id = m.Id,
                MaterielName = m.MaterielName,
                MaterielCode = m.MaterielCode,
                Specifications = m.Specifications,
                UnitsId = m.UnitsId,
                // 获取当前库存数量（这里需要根据实际情况查询库存表）
                StockQuantity = 0 // 暂时设为0，实际应该查询库存表
            }).ToList();
            
            return new PagedResultDto<MaterialSelectDto>(totalCount, materialDtos);
        }

        /// <summary>
        /// 获取生产工单选择列表
        /// </summary>
        /// <param name="input">查询条件</param>
        /// <returns>生产工单选择列表</returns>
        public async Task<PagedResultDto<WorkOrderSelectDto>> GetWorkOrdersForSelectAsync(GetWorkOrderSelectInputDto input)
        {
            var query = await _productionWorkOrdersRepository.GetQueryableAsync();
            
            // 关键字搜索
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(p => 
                    p.OrderCode.Contains(input.Keyword) ||
                    p.OrderName.Contains(input.Keyword) ||
                    p.ProductCode.Contains(input.Keyword) ||
                    p.ProductName.Contains(input.Keyword));
            }
            
            // 工单编号搜索
            if (!string.IsNullOrWhiteSpace(input.OrderCode))
            {
                query = query.Where(p => p.OrderCode.Contains(input.OrderCode));
            }
            
            // 工单名称搜索
            if (!string.IsNullOrWhiteSpace(input.OrderName))
            {
                query = query.Where(p => p.OrderName.Contains(input.OrderName));
            }
            
            // 产品编码搜索
            if (!string.IsNullOrWhiteSpace(input.ProductCode))
            {
                query = query.Where(p => p.ProductCode.Contains(input.ProductCode));
            }
            
            // 产品名称搜索
            if (!string.IsNullOrWhiteSpace(input.ProductName))
            {
                query = query.Where(p => p.ProductName.Contains(input.ProductName));
            }
            
            // 状态搜索
            if (!string.IsNullOrWhiteSpace(input.Status))
            {
                query = query.Where(p => p.Status == input.Status);
            }
            
            var totalCount = await AsyncExecuter.CountAsync(query);
            
            query = query.OrderByDescending(p => p.Id) // 按ID降序排序
                        .Skip(input.SkipCount)
                        .Take(input.MaxResultCount);
            
            var workOrders = await AsyncExecuter.ToListAsync(query);
            
            var workOrderDtos = workOrders.Select(w => new WorkOrderSelectDto
            {
                Id = w.Id,
                OrderCode = w.OrderCode,
                OrderName = w.OrderName,
                ProductCode = w.ProductCode,
                ProductName = w.ProductName,
                Specification = w.Specification,
                PlanQuantity = w.Quantity,
                Status = w.Status ?? "未开始"
            }).ToList();
            
            return new PagedResultDto<WorkOrderSelectDto>(totalCount, workOrderDtos);
        }

        /// <summary>
        /// 映射到DTO
        /// </summary>
        private async Task<ProductionReturnDto> MapToDto(ProductionReturn entity)
        {
            return new ProductionReturnDto
            {
                Id = entity.Id,
                ReturnCode = entity.ReturnCode,
                ReturnName = entity.ReturnName,
                WorkOrder = entity.WorkOrder,
                WarehouseId = entity.WarehouseId,
                WarehouseName = entity.WarehouseName,
                ReturnDate = entity.ReturnDate,
                Remark = entity.Remark,
                Status = entity.Status,
                StatusText = GetStatusText(entity.Status)
            };
        }

        /// <summary>
        /// 映射明细到DTO
        /// </summary>
        private async Task<ProductionReturnDetailDto> MapToDetailDto(ProductionReturnDetail entity)
        {
            return new ProductionReturnDetailDto
            {
                Id = entity.Id,
                ProductionReturnId = entity.ProductionReturnId,
                MaterialCode = entity.MaterialCode,
                MaterialName = entity.MaterialName,
                Size = entity.Size,
                Unit = entity.Unit,
                Num = entity.Num,
                Batch = entity.Batch,
                WarehouseId = entity.WarehouseId,
                WarehouseName = entity.WarehouseName
            };
        }

        /// <summary>
        /// 获取状态文本
        /// </summary>
        private string GetStatusText(string status)
        {
            return status switch
            {
                "草稿" => "草稿",
                "已确认" => "已确认",
                "已退料" => "已退料",
                _ => status ?? ""
            };
        }
    }
} 